/*
 * Copyright 2008 Lucas Tan.
 * This copyright notice must always remain intact whenever you use or distribute 
 * the source code contained in this file.
 * Any usage of any code in this file, either in derived work or
 * through the use of external linkage,
 * must always be credited with the author's name.
 * 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 * 
 * */
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace PassKeeper.Cryptography
{
	public sealed class PKDeriveBytes : DeriveBytes,IDisposable
	{
		/// <summary>
		/// Gets the default iteration count.
		/// </summary>
		public static int DefaultIterationCount
		{
			get
			{
				/*Do not ever change this value.*/
				return 1999;
			}
		}

		private readonly Rfc2898DeriveBytes _db;

		public PKDeriveBytes(byte[]passwordBytes,int iterationCount)
		{
		
			if (passwordBytes== null)
			{
				throw new ArgumentNullException("passwordBytes");
			}
			if (passwordBytes.Length == 0)
			{
				throw new ArgumentException("Cannot be empty.", "passwordBytes");
			}
			if (iterationCount <= 0)
			{
				throw new ArgumentException("Must be positive.", "iterationCount");
			}

			/* use our own sha512 hasher as Sys.Security.Crypto.SHA512Managed 
			 constructor may throw an InvalidOpExcep*/
			byte[] hash = (new SHA512ManagedHasher()).ComputeHash(passwordBytes);

			/*Doesn't matter if this throw an exception.*/
			_db = new Rfc2898DeriveBytes(passwordBytes, hash, iterationCount);
		}

		public  int IterationCount
		{
			get
			{
				return _db.IterationCount;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Must be positive.", "value");
				}

				_db.IterationCount= value;
			}
		}

		public override byte[] GetBytes(int cb)
		{
			return _db.GetBytes(cb);
		}

		public override void Reset()
		{
			_db.Reset();
		}

		#region IDisposable Members

		public void Dispose()
		{
			/*Do nothing since we don't have any unmanaged resources.*/
		}

		#endregion
	}
}
